;*****************************************************************************************************
;+
; NAME:
;       IGL_SAVEFILEWIDGET
;
; PURPOSE:
;
;       This is a subclass of a TOPLEVELBASE object which implements
;       a dialog to select a file and a graphic format output. They
;       can then be passed directly to the IGL_WINDOW::SaveWindow
;       method to save the content of the window.
;       A 'IGL_SAVEFILE' message is sent when the SAVE button is
;       pushed. At that time, recipient objects can invoke the
;       GetProperty method of the SaveFileWidget to get the filename and the graphic format
;       chosen by the user.
;
;
; AUTHORS:
;
;        RAPHAEL SADOUN
;        Graduate Student
;        Institut d'Astrophysique de Paris
;        98 bis boulevard Arago
;        75014 PARIS FRANCE
;        E-mail: raphael.sadoun@gmail.com
;
; SUPERCLASSES:
;
;       TOPLEVELBASE (Catalyst Library)
;
; SYNTAX:
;
;       widget = Obj_New('IGL_SaveFileWidget')
;
;
; CLASS_STRUCTURE:
;
;
;       class = {IGL_SaveFileWidget, $
;           INHERITS TOPLEVELBASE, $ ; This is a TOPLEVELBASE object
;           file:'', $               ; The filename selected by the user
;           format:'' $              ; The graphic format selected by the user 
;          }
;
;
; MODIFICATION_HISTORY:
;
;       Written by: Raphael Sadoun, 24 April 2012
;-
;*****************************************************************************************************
;+
; NAME:
;       IGL_SaveFileWidget::EVENTHANDLER
;
; PURPOSE:
;
;       This method is the event handler for the dialog widget.
;
; SYNTAX:
;
;       Called automatically by the event handling system
;
; ARGUMENTS:
;
;       event:  The event structure.
;
; KEYWORDS:
;
;       None.
;-
;*****************************************************************************************************
PRO IGL_SaveFileWidget::EventHandler, event

   @cat_pro_error_handler

   ;; Get the name of the widget generating the event. Branch on this.
  CASE event.name OF

     'BROWSEBUTTON': BEGIN      ; We want to change the currently selected file

        ;; Get the current name and path 
        dirField = self -> Get('dirField',/recursive_search)
        fileField = self -> Get('fileField',/recursive_search)
        dirField -> GetProperty, value=currentDir
        fileField -> GetProperty, value=currentFile

        ;; Compute the filter to pass to the Dialog_Pickfile dialog
        ;; depending on the currently selected format        
        formatList = self -> Get('FormatList',/recursive_search)
        formatList -> GetProperty, index=currentIndex
        currentFormat = self -> GetFormatName(currentIndex)
        CASE currentIndex OF           
           2: filter = '*.jpg;*.jpeg'
           4: filter = '*.tiff;*.tif'
           ELSE: filter = '*.'+strlowcase(currentFormat)
        ENDCASE

        ;; Call the file selection dialog
        file = Dialog_PickFile(/write,file=currentFile, $
                               path=currentDir, $
                               default_extension=currentFormat, $
                               filter=filter)

        IF (file NE '') THEN BEGIN ; If we have a valid filename

           ;; Get the name, path and extension of the file
           basename = FSC_Base_FileName(file,directory=dir,extension=ext)

           ;; Display the path in the directory text field
           dirField -> Setproperty, value=dir

           ;; Display the name in the file text field
           IF (ext NE '') THEN name = basename+'.'+ext ELSE name = basename
           fileField -> SetProperty, value=name

           ;; Resize the text fields to display all the characters
           xsize = strlen(dir) > strlen(name)
           xsize = (xsize*1.1) > 50
           dirField -> SetProperty, textsize=xsize
           fileField -> SetProperty, textsize=xsize

           ;; Set the format selection to the new selected format
           index = self -> GetFormatIndex(ext)
           IF (index GE 0) THEN BEGIN
              formatList = self -> Get('FORMATLIST',/recursive_Search)
              formatList -> SetProperty, index=index
              self.format = self -> GetFormatName(index)
           ENDIF

           ;; Save the filename
           self.file = file
           
        ENDIF
        
     END

     'FORMATLIST': BEGIN ; We want to change the output format

        ;; Get the name and extension of the currently selected file
        fileField = self -> Get('fileField',/recursive_search)
        fileField -> GetProperty, value=name
        basename =  fsc_base_filename(name,ext=ext)

        ;; Assign the selected format as extension of the file
        format = self -> GetFormatName(event.index)
        file = basename+'.'+format
        fileField -> SetProperty, value=file

        ;; Save the file and the format
        self.format = format
        self.file = file
        
     END

     'SAVEBUTTON': BEGIN

        self -> SendMessage, 'IGL_SAVEFILE'

        obj_destroy, self

     END

     'CANCELBUTTON': BEGIN
        obj_destroy, self
     END

     ELSE:

  ENDCASE

  ;; Report completion
  IF(obj_valid(self)) THEN self -> Report, /Completed

END

;*****************************************************************************************************
;+
; NAME:
;       IGL_SaveFileWidget::GETFORMATINDEX
;
; PURPOSE:
;
;       This method is used to get the index of a given format in the format list.
;
; SYNTAX:
;
;       index = self -> GetFormatIndex(format)
;
; ARGUMENTS:
;
;     FORMAT:               The name of the format for which we want
;                                      the corresponding index.
;
; KEYWORDS:
;
;     None.
;-
;*****************************************************************************************************
FUNCTION IGL_SaveFileWidget::GetFormatIndex, theFormat

  formatNames = ['PS','PNG','JPG','JPEG','BMP','TIFF','TIF']

  index = where(strupcase(theFormat) EQ formatNames)

  IF (index EQ 3) THEN index = 2
  IF (index GT 4) THEN index = 4

  return, index

END

;*****************************************************************************************************
;+
; NAME:
;       IGL_SaveFileWidget::GETFORMATLIST
;
; PURPOSE:
;
;       This method is used to get the list to pass to the DROPLIST
;       format selection widget.
;
; SYNTAX:
;
;       list = self -> GetFormatList()
;
; ARGUMENTS:
;
;     None.
;
; KEYWORDS:
;
;     None.
;-
;*****************************************************************************************************
FUNCTION IGL_SaveFileWidget::GetFormatList

  formatList = ['PostScript (*.ps)',$
                'Portable Network Graphics (*.png)',$
                'Joint Photographic Experts Group (*.jpg,*.jpeg)',$
                'Bitmap image (*.bmp)', $
                'Tagged Image File Format (*.tiff,*.tif)']

  return, formatList

END

;*****************************************************************************************************
;+
; NAME:
;       IGL_SaveFileWidget::GETFORMATNAME
;
; PURPOSE:
;
;       This method is used to get the name of the format
;       corresponding to a given index in the format list.
;
; SYNTAX:
;
;       format = self -> GetFormatList(index)
;
; ARGUMENTS:
;
;     INDEX:          The index in the format list.
;
; KEYWORDS:
;
;     None.
;-
;*****************************************************************************************************
FUNCTION IGL_SaveFileWidget::GetFormatName, index

  IF (n_elements(index) EQ 0) THEN index = 0

  retVal = ''
  
  formatNames = ['ps','png','jpg','bmp','tiff']

  IF ((index GE 0) AND (index LT 5)) THEN retVal = formatNames[index]

  return, retVal

END

;*****************************************************************************************************
;+
; NAME:
;       IGL_SaveFileWidget::GETPROPERTY
;
; PURPOSE:
;
;       This method is used to get the object's properties.
;
; SYNTAX:
;
;       self -> GetProperty
;
; ARGUMENTS:
;
;     None.
;
; KEYWORDS:
;
;     FILE:                 The full path (dir+name) of the currently selected file.                  
;
;     FORMAT:               The currently selected output format.
;     
;     _REF_EXTRA:     Any keywords appropriate for the superclass GetProperty method.
;-
;*****************************************************************************************************
PRO IGL_SaveFileWidget::GetProperty, FILE=file, $
                                     FORMAT=format, $
                                     _REF_EXTRA=extra

  IF (arg_present(file)) THEN file = self.file
  IF (arg_present(format)) THEN format = self.format

  self -> TOPLEVELBASE::GetProperty, _Extra=extra

  self -> Report, /completed

END

;*****************************************************************************************************
;+
; NAME:
;       IGL_SaveFileWidget::SETPROPERTY
;
; PURPOSE:
;
;       This method is used to set the object's properties.
;
; SYNTAX:
;
;       self -> SetProperty
;
; ARGUMENTS:
;
;     None.
;
; KEYWORDS:
;
;     _EXTRA:       Any keyword accepted by the SetProperty method of
;                   the TOPLEVELBASE superclass.
;-
;*****************************************************************************************************
PRO IGL_SaveFileWidget::SetProperty, _Extra=extra

  self -> TOPLEVELBASE::SetProperty, _Extra=extra

  self -> Report, /completed

END

;*****************************************************************************************************
;+
; NAME:
;       IGL_SaveFileWidget::CLEANUP
;
; PURPOSE:
;
;       This is the IGL_SaveFileWidget object class destructor method.
;
; SYNTAX:
;
;       Called automatically when the object is destroyed.
;
;
; ARGUMENTS:
;
;     None.
;
; KEYWORDS:
;
;     None.
;-
;*****************************************************************************************************
PRO IGL_SaveFileWidget::Cleanup

  self -> TopLevelBase::Cleanup

  self -> Report, /Completed

END

;*****************************************************************************************************
;+
; NAME:
;       IGL_SaveFileWidget::INIT
;
; PURPOSE:
;
;       This is the IGL_SaveFileWidget object class creator method.
;
; SYNTAX:
;
;       Called automatically when the object is created.
;
; ARGUMENTS:
;
;     None.
;
; KEYWORDS:
;
;     TITLE:            The title of the TopLevelBase widget. The
;                            default is  'Save to file'.
;
;     INITIALFILE:  The path+name of the initially selected file. The
;                             default is 'graphic.ps' which selects a
;                             file named 'graphic.ps' in the current
;                             directory with the PostScript output format.
;
;     _EXTRA:       Any keywords accepted by the TOPLEVELBASE::Init method.
;
;-
;*****************************************************************************************************
FUNCTION IGL_SaveFileWidget::Init, TITLE=title, $
                                   INITIALFILE=initialFile, $
                                   _REF_EXTRA=extra

  ;; Default keyword values
  IF (n_elements(title) EQ 0) THEN title = 'Save to file'
  IF (n_elements(initialFile) EQ 0) THEN initialFile = 'graphic.ps'
  IF (initialFile EQ '') THEN initialFile = 'graphic.ps'

  ;; Initialize the TopLevelBase superclass
  ok = self -> TopLevelBase::Init(title=title, $
                                  /no_mbar, $
                                  tlb_frame_attr=1, $
                                  column=1, $
                                  _extra=extra)

  IF (NOT ok) THEN return, 0

  ;; Create the widgets of the dialog
  basename = fsc_base_filename(initialFile,directory=dir,extension=ext)
  IF (ext NE '') THEN name = basename+'.'+ext ELSE name = basename

  mainBase = obj_new('BaseWidget',self,column=1,frame=1)
  topBase = obj_new('BaseWidget',mainBase,row=1,/base_align_center,xpad=0,ypad=0)
  
  leftBase = obj_new('BaseWidget',topbase,column=1,xpad=0,ypad=0)
  xsize = strlen(dir) > strlen(name)
  xsize = (xsize*1.1) > 50 
  dirField = obj_new('FieldWidget',leftBase,xsize=xsize,title='Directory:',name='DIRFIELD',/noedit,value=dir,labelsize=80)
  fileField = obj_new('FieldWidget',leftBase,xsize=xsize,title='Filename:',name='FILEFIELD',/noedit,value=name,labelsize=80)
  
  rightBase = obj_new('BaseWidget',topBase,column=1,/base_align_center)
  root_dir = ProgramRootDir(/TWOUP)
  sub_dir = ['resource','bitmaps']
  mapfile = filepath(root_dir=root_dir,subdirectory=sub_dir,'IGL_Folder.bmp')
  browseButton = obj_new('ButtonWidget',rightBase,value=mapfile,tooltip='Browse...',name='BROWSEBUTTON',/bitmap)  
  
  formatBase = obj_new('BaseWidget',mainBase,row=1,xpad=0,ypad=0)
  formats = self -> GetFormatList()
  formatList = obj_new('DropListWidget',formatBase,value=formats,name='FORMATLIST',title='Format: ',label_size=80,/dynamic)
  index = self -> GetFormatIndex(ext)
  formatList -> SetProperty, index=index
  buttonBase = obj_new('BaseWidget',self,row=1,/align_center,/grid_layout)
  saveButton = obj_new('ButtonWidget',buttonBase,name='SAVEBUTTON',value='Save')
  cancelButton = obj_new('ButtonWidget',buttonBase,name='CANCELBUTTON',value='Cancel')

  ;; Save the initial selection
  self.file = initialFile
  self.format = self -> GetFormatName(index)

  ;; Report completion
  self -> Report, /Completed

  return, 1
  
END

;*****************************************************************************************************
;
; NAME:
;       IGL_SAVEFILEWIDGET CLASS DEFINITION
;
; PURPOSE:
;
;       This is the IGL_SaveFileWidget object's structure definition code.
;
;*****************************************************************************************************
PRO IGL_SaveFileWidget__define, class

  COMPILE_OPT idl2, HIDDEN

  class = {IGL_SaveFileWidget, $
           INHERITS TOPLEVELBASE, $ ; This is a TOPLEVELBASE object
           file:'', $               ; The filename selected by the user
           format:'' $              ; The graphic format selected by the user 
          }

  struct_hide, class

END
